#include "sprite.h"

#include <iostream>

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>


////////////////////////  MACROS  //////////////////////////
#define MIL_SEG		50
#define ANCHO_PANT  462
#define ALTO_PANT	640
#define LIM_INF		504
#define FRAME 		42 	//frames de 42x42 pixeles 
////////////////////////////////////////////////////////////



/////////////////////////  MAPA  ///////////////////////////
// Mapa de tiles
// cada tile tiene 42x42 píxeles una pantalla tiene 10x12 tiles
int mapa[12][11] = {{4,4,4,4,4,4,4,4,4,4,4},
					{4,3,5,3,5,3,5,3,5,3,4},
					{2,2,2,2,2,2,2,2,2,2,2},
					{2,2,2,2,2,2,2,2,2,2,2},
					{2,2,2,2,2,2,2,2,2,2,2},
					{2,2,2,2,2,2,2,2,2,2,2},
					{0,0,0,0,0,0,0,0,0,0,0},
					{1,1,1,1,1,1,1,1,1,1,1},
					{1,1,1,1,1,1,1,1,1,1,1},
					{1,1,1,1,1,1,1,1,1,1,1},
					{1,1,1,1,1,1,1,1,1,1,1},
					{0,0,0,0,0,0,0,0,0,0,0}};
					
Frame tile;
Frame tile1;
Frame tile2;
Frame tile3;
Frame tile4;
Frame tile5;
Sprite suelo[6];
////////////////////////////////////////////////////////////



//////////////// CREACION DE SPRITES+FRAMES ////////////////
Frame frana;
Sprite rana(1);

Frame fauto1;
Frame fauto2;
Frame fauto3;
Frame fcamion;

Frame ftortugas;
Frame ftronco;

Sprite auto1(1);
Sprite auto2(1);
Sprite auto3(1);
Sprite camion(1);

Sprite tortugas1(1);
Sprite tortugas2(1);
Sprite tronco1(1);
Sprite tronco2(1);
////////////////////////////////////////////////////////////



//////////////////////  V.GLOBALES  ////////////////////////
int salir=0;
SDL_Surface *pantalla;
TTF_Font *fuente;
Uint32 ini_milisegundos, fin_milisegundos, frametime;
////////////////////////////////////////////////////////////



//////////////////////  ESTRUCTURAS  ///////////////////////
// info de la rana
struct srana {
	int x,y;
} jugador;

// info de los enemigos(autos)
struct enemigos {
	int x,y;
} enemigo[4];

// info de los amigos(tortugas y troncos)
struct amigos {
	int x,y;
} amigo[4];
////////////////////////////////////////////////////////////



////////////////   INICIACION DE POSICIONES  ///////////////
void inicio_jugador() {
	jugador.x=250;
	jugador.y=462;
}

void inicio_enemigos() {
	enemigo[0].x=ANCHO_PANT;
	enemigo[0].y=(FRAME*9);
	
	enemigo[1].x=ANCHO_PANT;
	enemigo[1].y=(FRAME*8);
	
	enemigo[2].x=ANCHO_PANT;
	enemigo[2].y=(FRAME*10);
	
	enemigo[3].x=ANCHO_PANT;
	enemigo[3].y=(FRAME*7);
}

void inicio_amigos() {
	amigo[0].x=ANCHO_PANT;
	amigo[0].y=(FRAME*2);
	
	amigo[1].x=ANCHO_PANT;
	amigo[1].y=(FRAME*3);
	
	amigo[2].x=ANCHO_PANT;
	amigo[2].y=(FRAME*4);
	
	amigo[3].x=ANCHO_PANT;
	amigo[3].y=(FRAME*5);
}
////////////////////////////////////////////////////////////



///////////////////////   GRAFICOS   ///////////////////////
void dibujar_mapa(int mapa[12][11]){
	int i,j,x,y,t;

	for (i=0 ; i<12 ; i++) {
		for (j=0 ; j<11 ; j++) {
			t=mapa[i][j];
			// calculo la posición del tile
			x=j*FRAME;
			y=i*FRAME;
			// dibujamos el tile
			suelo[t].setx(x);
			suelo[t].sety(y);
			suelo[t].dibujar(pantalla);
		}
	}

}

void dibujar_jugadores(){
	// dibuja rana
	rana.setx(jugador.x);
	rana.sety(jugador.y);
	rana.dibujar(pantalla);
}

void dibujar_enemigos(){
	// Dibuja enemigo0
	auto1.setx(enemigo[0].x);
	auto1.sety(enemigo[0].y);
	auto1.dibujar(pantalla);
	
	// Dibuja enemigo1
	auto2.setx(enemigo[1].x);
	auto2.sety(enemigo[1].y);
	auto2.dibujar(pantalla);
	
	// Dibuja enemigo2
	auto3.setx(enemigo[2].x);
	auto3.sety(enemigo[2].y);
	auto3.dibujar(pantalla);
	
	// Dibuja enemigo3
	camion.setx(enemigo[3].x);
	camion.sety(enemigo[3].y);
	camion.dibujar(pantalla);
}

void dibujar_amigos(){
	// Dibuja amigo0
	tronco1.setx(amigo[0].x);
	tronco1.sety(amigo[0].y);
	tronco1.dibujar(pantalla);
	
	// Dibuja amigo2
	tortugas1.setx(amigo[1].x);
	tortugas1.sety(amigo[1].y);
	tortugas1.dibujar(pantalla);
	
	// Dibuja amigo2
	tronco2.setx(amigo[2].x);
	tronco2.sety(amigo[2].y);
	tronco2.dibujar(pantalla);
	
	// Dibuja amigo3
	tortugas2.setx(amigo[3].x);
	tortugas2.sety(amigo[3].y);
	tortugas2.dibujar(pantalla);
}

// dibuja el mapa + los sprites
void dibujar_escena(SDL_Surface *pantalla) {
	
	dibujar_mapa(mapa);
	dibujar_amigos();	
	dibujar_jugadores();	
	dibujar_enemigos();
	
	// ¿Nos piso un auto?
	if ((auto1.colision(rana) == TRUE)||(auto2.colision(rana) == TRUE)||
		(auto3.colision(rana) == TRUE)||(camion.colision(rana) == TRUE))
		
		inicio_jugador();
	
	// Mostramos todo el frame
	SDL_Flip(pantalla);
}
////////////////////////////////////////////////////////////



///////////////////////   SPRITES   ///////////////////////
int iniciar_sprites() {

	tile.cargar("piso.png");
	suelo[0].agregar_frame(tile);

	tile1.cargar("calle.png");
	suelo[1].agregar_frame(tile1);

	tile2.cargar("agua.png");
	suelo[2].agregar_frame(tile2);

	tile3.cargar("nido.png");
	suelo[3].agregar_frame(tile3);
	
	tile4.cargar("pasto.png");
	suelo[4].agregar_frame(tile4);
	
	tile5.cargar("flores.png");
	suelo[5].agregar_frame(tile5);
	
	frana.cargar("rana.png");
	rana.agregar_frame(frana);
	
	fauto1.cargar("auto1.png");
	auto1.agregar_frame(fauto1);
	
	fauto2.cargar("auto2.png");
	auto2.agregar_frame(fauto2);
	
	fauto3.cargar("auto4.png");
	auto3.agregar_frame(fauto3);
	
	fcamion.cargar("camion.png");
	camion.agregar_frame(fcamion);
	
	ftortugas.cargar("tortugas3.png");
	tortugas1.agregar_frame(ftortugas);
	tortugas2.agregar_frame(ftortugas);
	
	ftronco.cargar("tronco.png");
	tronco1.agregar_frame(ftronco);
	tronco2.agregar_frame(ftronco);
	
	return 0;
}

void mover_enemigos(){
	if(enemigo[0].x <= -FRAME)
		enemigo[0].x=ANCHO_PANT;
	enemigo[0].x=(enemigo[0].x-(10));
	
	if(enemigo[1].x >= ANCHO_PANT+FRAME)
		enemigo[1].x=(-FRAME);
	enemigo[1].x=(enemigo[1].x+(8));
	
	if(enemigo[2].x >= ANCHO_PANT+FRAME)
		enemigo[2].x=(-FRAME);
	enemigo[2].x=(enemigo[2].x+(5));
	
	if(enemigo[3].x <= (-FRAME)*2)
		enemigo[3].x=ANCHO_PANT;
	enemigo[3].x=enemigo[3].x-(2);
}

void mover_amigos(){
	if(amigo[0].x == (-FRAME)*3)
		amigo[0].x=ANCHO_PANT;
	amigo[0].x=(amigo[0].x-(4));
	
	if(amigo[1].x == (-FRAME)*3)
		amigo[1].x=ANCHO_PANT;
	amigo[1].x=(amigo[1].x-(2));
	
	if(amigo[2].x == (-FRAME)*3)
		amigo[2].x=ANCHO_PANT;
	amigo[2].x=(amigo[2].x-(3));
	
	if(amigo[3].x == (-FRAME)*3)
		amigo[3].x=ANCHO_PANT;
	amigo[3].x=amigo[3].x-(1);
}

void finalizar_sprites() {
	suelo[0].finalizar();
	suelo[1].finalizar();
	suelo[2].finalizar();
	suelo[3].finalizar();
	suelo[4].finalizar();
	suelo[5].finalizar();
					
	rana.finalizar();
	
	auto1.finalizar();
	auto2.finalizar();
	auto3.finalizar();
	camion.finalizar();
	
	//solo finalizo 1 de cada tipo, ya que usan mismo frame!!!!!!!!!!!!!!!
	//verificar siempre en todos, sino da ERROR: double free or corruption
	tortugas1.finalizar();
	tronco1.finalizar();
}
////////////////////////////////////////////////////////////



///////////////////// TEMPORIZACION ////////////////////////
void ResetTimeBase() {
	ini_milisegundos=SDL_GetTicks();
}

int CurrentTime() {
	fin_milisegundos=SDL_GetTicks();
	return fin_milisegundos-ini_milisegundos;
}
////////////////////////////////////////////////////////////



/////////////////////  PRINCIPAL  //////////////////////////
int main(int argc, char *argv[]) {
	SDL_Event event;
	Uint8 *keys;
	
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		printf("No se pudo iniciar SDL: %s\n",SDL_GetError());
		return 1;
	}

	pantalla = SDL_SetVideoMode(ANCHO_PANT,ALTO_PANT,32,SDL_DOUBLEBUF);
	if (pantalla == NULL) {
		printf("No se puede inicializar el modo gráfico:%s \n",SDL_GetError());
		return 1;
	}
	
	atexit(SDL_Quit);
	inicio_enemigos();
	inicio_amigos();
	inicio_jugador();
	iniciar_sprites();

	while (salir == 0) {
		// temporizacion
		ResetTimeBase();
		
		dibujar_escena(pantalla);
		
		// damos vida a los sprites
		mover_enemigos();
		mover_amigos();
	
		// consultamos el estado del teclado
		keys=SDL_GetKeyState(NULL);
	
		if((keys[SDLK_UP]) && (jugador.y > 0)) 
			{jugador.y=jugador.y-(5);}

		if((keys[SDLK_DOWN]) && (jugador.y < (LIM_INF-FRAME)))
			{jugador.y=jugador.y+(5);}
	
		if((keys[SDLK_LEFT]) && (jugador.x > 0)) 
			{jugador.x=jugador.x-(5);}
	
		if((keys[SDLK_RIGHT]) && (jugador.x < (ANCHO_PANT-FRAME))) 
			{jugador.x=jugador.x+(5);}

		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT)
				salir=1;
				
			if (event.type == SDL_KEYDOWN) {
				if (event.key.keysym.sym == SDLK_ESCAPE) 
					salir=1;
			}
		}
		
		//Este bucle se ejecutará mientras no hayan transcurrido, MIL_SEG milisegundos
		//A seguramos que no se van a producir más de un frame cada MIL_SEG.
		do {
			frametime=CurrentTime();
		} while (frametime<MIL_SEG);
	}
	
	finalizar_sprites();
	return 0;
}
////////////////////////////////////////////////////////////
